<template>
  <div class="flow-main-main">
    <div class="flow-main">
      <div class="flow-row">
        <div class="flow-node start-end">流程开始</div>
      </div>

      <div class="flow-row" v-for="(flow, flowIndex) in value" :key="flowIndex">
        <add-btn @command="handleAdd($event, flowIndex)" :class="hasConditions(flow.items) ? 'btn-large' : ''"></add-btn>
        <div class="flow-content-border" v-if="hasConditions(flow.items) && flow.items.length > 1"></div>
        <div class="flow-condition-btn" v-if="hasConditions(flow.items)">
          <el-button size="small" round @click="addConditions(flowIndex)">添加条件</el-button>
        </div>
        <div class="flow-content-main">
          <div class="flow-content" v-for="(item, itemIndex) in flow.items" :key="itemIndex">
            <div class="flow-node flow-arrows-2" v-if="item.conditions"></div>

            <condition-card v-if="item.conditions"
                            :compare-options="compareOptions" :conditions="item.conditions"
                            @edit="handleEditCondition(flowIndex, itemIndex)" @delete="deleteCondition(flowIndex, itemIndex)">
            </condition-card>

            <div class="flow-node-main" v-for="(node, nodeIndex) in item.nodes" :key="nodeIndex">
              <add-btn v-if="item.conditions" :show-condition="!item.conditions"
                       @command="handleAdd($event, flowIndex, itemIndex, nodeIndex)"></add-btn>
              <div class="flow-node-arrows">
                <div class="flow-node">
                  <div class="flow-item" v-for="(approver, approverIndex) in node.approvers" :key="approverIndex">
                    <div class="flow-tool">
                      <el-input size="small" v-model="approver.nodeName" placeholder="请输入审批节点名" :disabled="!edit && approver.isLocked"/>
                    </div>
                    <el-divider></el-divider>
                    <div class="flow-user">
                      <el-input size="small" v-model="approver.userName" placeholder="审批人" disabled>
                        <i v-if="edit || !approver.isLocked" slot="suffix" class="el-input__icon el-icon-search" @click="openUserDialog(approver)"></i>
                      </el-input>
                    </div>
                    <el-divider></el-divider>
                    <div class="flow-tool flow-btn">
                      <el-link type="primary" :underline="false" @click="addItem(flowIndex, itemIndex, nodeIndex, approverIndex)"><i class="el-icon-circle-plus-outline"></i></el-link>
                      <el-link v-if="edit || !item.isLocked" type="danger" :underline="false" @click="deleteItem(flowIndex, itemIndex, nodeIndex, approverIndex)"><i class="el-icon-delete"></i></el-link>
                      <el-checkbox v-if="edit" v-model="approver.isLocked" @change="handleLocked">锁定</el-checkbox>
                    </div>
                  </div>
                </div>
              </div>
            </div>
            <div class="flow-node flow-arrows-2" v-if="flow.items.length > 1 && item.conditions"></div>
          </div>
        </div>
        <div class="flow-content-border" v-if="hasConditions(flow.items) && flow.items.length > 1"></div>
      </div>

      <div class="flow-row">
        <add-btn @command="handleAdd($event, value.length)"></add-btn>
        <div class="flow-node-arrows">
          <div class="flow-node start-end" style="border-radius: 50%;">流程结束</div>
        </div>
      </div>
    </div>

    <user-table ref="userTable" :multiple-mode="false" @set-value="setUsers"></user-table>
    <condition-edit ref="conditionEdit" :compare-options="compareOptions" @set-value="setConditions"></condition-edit>
  </div>
</template>

<script>
import "./flow.scss";
import UserTable from "@/components/UserSelector/userTable";
import ConditionEdit from "./components/conditionEdit";
import AddBtn from "./components/addBtn";
import ConditionCard from "./components/conditionCard";

export default {
  name: "Index",
  components: {
    UserTable,
    ConditionEdit,
    AddBtn,
    ConditionCard
  },
  props: {
    value: {
      type: Array,
      default: () => []
    },
    edit: {
      type: Boolean,
      default: false
    },
    table: String
  },
  model: {
    prop: 'value',
    event: 'change'
  },
  data() {
    return {
      compareOptions: [],
      selectedNode: undefined,
      branch: false,
      flowIndex: 0,
      itemIndex: 0,
      nodeIndex: 0,
      editCondition: false
    }
  },
  created() {
    this.getDicts("flow_condition_compare").then(res => {
      this.compareOptions = res;
    });
  },
  methods: {
    handleAdd(command, flowIndex, itemIndex, nodeIndex) {
      this.flowIndex = flowIndex;
      this.itemIndex = itemIndex;
      this.nodeIndex = nodeIndex;
      if (command === 'node') {
        this.addNode();
      } else if (command === 'node2') {
        this.addNode2();
      } else if (command === 'condition') {
        this.addConditionBranch();
      }
    },
    addNode() {
      const node = {
        items: [{
          nodes: [{
            approvers: [{
              nodeName: "审批",
              userName: undefined,
              userCode: undefined,
              isLocked: false
            }]
          }]
        }]
      };
      this.value.splice(this.flowIndex, 0, node);
      this.$emit("change", this.value);
    },
    addNode2() {
      const items = this.value[this.flowIndex].items;
      const nodes = items[this.itemIndex].nodes;
      const approver = {
        approvers: [{
          nodeName: "审批",
          userName: undefined,
          userCode: undefined,
          isLocked: false
        }]
      };
      nodes.splice(this.nodeIndex, 0, approver);
    },
    addItem(flowIndex, itemIndex, nodeIndex, approverIndex) {
      const items = this.value[flowIndex].items;
      const item = items[itemIndex];
      const approvers = item.nodes[nodeIndex].approvers;
      const approver = {
        nodeName: "审批",
        userName: undefined,
        userCode: undefined,
        isLocked: false
      };
      approvers.splice(approverIndex + 1, 0, approver);
      this.$emit("change", this.value);
    },
    addConditionBranch() {
      if (!this.table) {
        this.msgError("请先选择对应的表");
        return;
      }
      this.branch = true;
      this.editCondition = false;
      this.openConditions();
    },
    addConditions(flowIndex) {
      if (!this.table) {
        this.msgError("请先选择对应的表");
        return;
      }
      this.branch = false;
      this.editCondition = false;
      this.flowIndex = flowIndex;
      this.openConditions();
    },
    handleEditCondition(flowIndex, itemIndex) {
      if (!this.table) {
        this.msgError("请先选择对应的表");
        return;
      }
      this.editCondition = true;
      this.flowIndex = flowIndex;
      this.itemIndex = itemIndex;
      const items = this.value[flowIndex].items;
      const conditions = items[itemIndex].conditions;
      this.openConditions(conditions);
    },
    openConditions(conditions = []) {
      this.$refs.conditionEdit.init(this.table, conditions);
    },
    setConditions(conditions) {
      if (this.editCondition) {
        const items = this.value[this.flowIndex].items;
        const item = items[this.itemIndex];
        item.conditions = conditions;
      } else {
        const item = {
          conditions: conditions,
          nodes: [{
            approvers: [{
              nodeName: "审批",
              userName: undefined,
              userCode: undefined,
              isLocked: false
            }]
          }]
        };
        if (this.branch) {
          const items = {
            items: [item]
          };
          this.value.splice(this.flowIndex, 0, items);
        } else {
          const items = this.value[this.flowIndex].items;
          items.push(item);
        }
      }
    },
    deleteCondition(flowIndex, itemIndex) {
      const items = this.value[flowIndex].items;
      if (items.length > 1) {
        items.splice(itemIndex, 1);
      } else {
        this.value.splice(flowIndex, 1);
      }
    },
    deleteItem(flowIndex, itemIndex, nodeIndex, approverIndex) {
      const items = this.value[flowIndex].items;
      const item = items[itemIndex];
      const approvers = item.nodes[nodeIndex].approvers;
      if (approvers.length > 1) {
        approvers.splice(approverIndex, 1);
      } else {
        if (item.nodes.length > 1) {
          item.nodes.splice(nodeIndex, 1);
        } else {
          if (items.length > 1) {
            items.splice(itemIndex, 1);
          } else {
            this.value.splice(flowIndex, 1);
          }
        }
      }
      this.$emit("change", this.value);
    },
    openUserDialog(item) {
      this.selectedNode = item;

      const users = [];
      if (item.userCode) {
        users.push({
          code: item.userCode,
          name: item.userName
        });
      }
      this.$refs.userTable.init(users);
    },
    setUsers(users) {
      if (users && users.length > 0) {
        this.$set(this.selectedNode, "userName", users[0].name);
        this.$set(this.selectedNode, "userCode", users[0].code);
      }
      this.$emit("change", this.value);
    },
    handleLocked() {
      this.$emit("change", this.value);
    },
    setContentHeight() {
      const contentMains = document.getElementsByClassName("flow-content-main");
      if (contentMains && contentMains.length > 0) {
        this.$lodash.forEach(contentMains, item => {
          item.style.height = "";
          item.style.marginTop = "";
        })
      }
      const conditionBtns = document.getElementsByClassName("flow-condition-btn");
      if (conditionBtns && conditionBtns.length > 0) {
        this.$lodash.forEach(conditionBtns, item => {
          item.style.height = "";
          item.style.marginTop = "";
        })
      }
      const resetArrows = document.getElementsByClassName("flow-arrows-2");
      if (resetArrows && resetArrows.length > 0) {
        this.$lodash.forEach(resetArrows, item => {
          item.style.width = "";
        })
      }

      const rows = document.getElementsByClassName("flow-row");
      if (rows && rows.length > 0) {
        this.$lodash.forEach(rows, item => {
          let mainHeight = 0; // item.clientHeight;
          const mainWidth = item.clientWidth - 124;

          const contents = item.getElementsByClassName("flow-content");
          const contentBorders = item.getElementsByClassName("flow-content-border");
          if (contents && contents.length > 0 && contentBorders && contentBorders.length > 0) {
            const firstContent = contents[0];
            const lastContent = contents[contents.length - 1];
            const firstHeight = firstContent.clientHeight;
            const lastHeight = lastContent.clientHeight;

            this.$lodash.forEach(contents, item => {
              mainHeight = mainHeight + item.clientHeight;
              const width = item.clientWidth;
              if (width < mainWidth) {
                const addWidth = mainWidth - width + 60;
                const arrows = item.getElementsByClassName("flow-arrows-2");
                const lastArrow = arrows && arrows.length > 0 ? arrows[arrows.length - 1] : null;
                if (lastArrow) {
                  lastArrow.style.width = addWidth + 'px';
                  // lastArrow.style.minWidth = addWidth + 'px';
                }
              }
            });

            this.$lodash.forEach(contentBorders, item => {
              item.style.height = (mainHeight - firstHeight / 2 - lastHeight / 2 + 2) + 'px';
              item.style.marginTop = ((firstHeight / 2) - 1) + 'px';
            });
          }
        })
      }
    },
    hasConditions(items) {
      let has = false;
      this.$lodash.forEach(items, item => {
        if (item.conditions) {
          has = true;
          return false;
        }
      })
      return has;
    }
  },
  watch: {
    value: {
      handler(val) {
        this.$nextTick(() => {
          this.setContentHeight();
        });
      },
      deep: true
    }
  },
  mounted() {
    this.setContentHeight();
  }
}
</script>

<style scoped lang="scss">

</style>
